package com.hulman.oms.job;


import com.hulman.oms.annotation.TaskListener;
import com.hulman.oms.annotation.TaskTimeout;
import com.hulman.oms.bean.Task;
import com.hulman.oms.service.TaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Component
@Slf4j
public class TaskTimeoutJob
{
    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private TaskService taskService;

    /**
     *
     */
    //@Scheduled(cron = "*/2 * * * * ?")//调试节奏
    @Scheduled(cron = "0 * * * * ?")
    public void checkTaskTimeout()
    {
        List<Task> timeoutTasks = taskService.findTimeoutTasks();
        if (timeoutTasks.size() == 0)
        {
            return;
        }
        Map<String, Object> beans = applicationContext.getBeansWithAnnotation(TaskListener.class);
        beans.values().forEach(bean ->
        {
            Method[] methods = bean.getClass().getDeclaredMethods();
            Arrays.stream(methods).forEach(method ->
            {
                TaskTimeout taskTimeout = AnnotationUtils.findAnnotation(method, TaskTimeout.class);
                if (taskTimeout != null)
                {
                    String name = taskTimeout.name();
                    String tag = taskTimeout.tag();
                    timeoutTasks.stream().filter(task -> name.equals(task.getName()) && tag.equals(task.getTag())).forEach(task ->
                    {
                        try
                        {
                            method.invoke(bean, task);
                        } catch (IllegalAccessException e)
                        {
                            throw new RuntimeException(e);
                        } catch (InvocationTargetException e)
                        {
                            throw new RuntimeException(e);
                        }
                    });
                }
            });
        });
    }
}
